/** @file libsvm_dataset.h
 *
 *  The class for supporting the LibSVM format.
 *
 *  @author Dongryeol Lee (drselee@gmail.com)
 */

#ifndef CORE_DATA_LIBSVM_DATASET_H
#define CORE_DATA_LIBSVM_DATASET_H

#include <armadillo>
#include <boost/mpi.hpp>
#include <string>
#include <vector>

#include "core/data/alias_sparse_vec.h"
#include "core/data/dataset.h"

namespace core {
namespace data {

class LibSVMParser;

class SparseDataset : public core::data::Dataset {
  private:
    friend class core::data::LibSVMParser;

  private:

    std::vector< arma::SpCol<double> * > col_collections_;

    /** @brief The view consisting of none-labels.
     */
    std::vector < core::data::alias_sparse_vec * > raw_point_collections_;

    /** @brief The view consisting of the targets.
     */
    std::vector < core::data::alias_sparse_vec * > raw_target_collections_;

  public:

    void as_dense_matrix(arma::mat *dense_matrix_out) const;

    ~SparseDataset();

    double average_num_points() const ;

    arma::SpCol<double> &get_instance(int point_id) ;

    const arma::SpCol<double> &get_instance(int point_id) const ;

    core::data::alias_sparse_vec &get_instance(
      int point_id,
      core::data::alias_sparse_vec **targets_out) ;

    const core::data::alias_sparse_vec &get_instance(
      int point_id,
      const core::data::alias_sparse_vec **targets_out) const ;

    void Init(int num_attributes, int num_points) ;

    void Init(
      boost::mpi::communicator &world,
      const std::string &file_name_in, bool from_single_file) ;

    bool Init(const std::string &file_name_in) ;

    int num_points() const ;

    void RandomGenerate(
      boost::mpi::communicator &world, int num_dimensions, int num_points) ;
};
}
}

#endif
